home *** CD-ROM | disk | FTP | other *** search
- unit clocks;
- {$X+} {allow discardable function results}
-
- { Clock-on-a-menubar OOP extension to Turbo Vision apps
-
- Copyright (c) 1990 by Danny Thorpe
-
- Alarms have not been implemented.
- }
-
- interface
- uses dos, objects, drivers, views, menus, dialogs, app, msgbox;
-
- const cmClockChangeDisplay = 1001;
- cmClockSetAlarm = 1002;
-
- ClockNoSecs = 0;
- ClockDispSecs = 1;
- Clock12hour = 0;
- Clock24hour = 1;
-
- type
-
- ClockDataRec = record
- Format: word;
- Seconds: word;
- RefreshStr: String[2];
- end;
-
-
- PClockMenu = ^TClockMenu;
- TClockMenu = object(TMenuBar)
- ClockOptions: ClockDataRec;
- Refresh: byte;
- LastTime: DateTime;
- TimeStr: string[10];
- constructor Init(var Bounds: TRect; Amenu: PMenu);
- procedure Draw; virtual;
- procedure Update; virtual;
- procedure SetRefresh(Secs: integer); virtual;
- procedure SetRefreshStr( Secs: string); virtual;
- procedure ClockChangeDisplay; virtual;
- procedure HandleEvent( var Event: TEvent); virtual;
- function FormatTimeStr(h,m,s:word):string; virtual;
- end;
-
-
-
-
- implementation
-
-
- function LeadingZero(w : Word) : String;
- var
- s : String;
- begin
- Str(w:0,s);
- if Length(s) = 1 then
- s := '0' + s;
- LeadingZero := s;
- end;
-
-
-
- constructor TClockMenu.Init(var Bounds: TRect; AMenu: PMenu);
- var Temp: PMenuBar;
- ClockMenu: PMenu;
- R: TRect;
- begin
- ClockMenu:= NewMenu(NewSubMenu('~'#0'~Clock ', hcNoContext, NewMenu(
- NewItem('~C~hange display','',0,cmClockChangeDisplay, hcNoContext,
- NewItem('Set ~A~larm','', 0, cmClockSetAlarm, hcNoContext,
- nil))),
- AMenu^.Items));
- { ^^ tack passed menubar on end of new clock menu }
- ClockMenu^.Default:= AMenu^.Default;
-
- TMenuBar.Init(Bounds, ClockMenu);
-
- fillchar(LastTime,sizeof(LastTime),#$FF); {fill with 65000's}
- TimeStr:='';
- ClockOptions.Format:= Clock24Hour;
- ClockOptions.Seconds:= ClockDispSecs;
- SetRefresh(1);
- end;
-
-
-
- procedure TClockMenu.Draw;
- var P: PMenuItem;
- begin
- P:= FindItem(#0);
- if P <> nil then
- begin
- DisposeStr(P^.Name);
- P^.Name:= NewStr('~'#0'~'+TimeStr);
- end;
- TMenuBar.Draw;
- end;
-
-
-
- procedure TClockMenu.Update;
- var h,m,s,hund: word;
- begin
- GetTime(h,m,s,hund);
- if abs(s-LastTime.sec) >= Refresh then
- begin
- with LastTime do
- begin
- Hour:=h;
- Min:=m;
- Sec:=s;
- end;
- TimeStr:= FormatTimeStr(h,m,s);
- DrawView;
- end;
- end;
-
-
-
-
- procedure TClockMenu.SetRefresh(Secs: integer);
- begin
- if Secs > 59 then
- Secs := 59;
- if Secs < 0 then
- Secs := 0;
- Refresh:= Secs;
- Str(Refresh:2,ClockOptions.RefreshStr);
- end;
-
-
-
- procedure TClockMenu.SetRefreshStr( Secs: string);
- var temp,code: integer;
- begin
- val(Secs, temp, code);
- if code = 0 then
- SetRefresh(temp);
- end;
-
-
-
-
- procedure TClockMenu.ClockChangeDisplay;
-
- var
- D: PDialog;
- Control: PView;
- Command: word;
- temp,code: integer;
- R: TRect;
- ClockData : ClockDataRec;
-
- begin
-
- ClockData := ClockOptions;
-
- R.Assign(14,3,48,15);
- D:= new(PDialog, Init(R, 'Clock Display'));
-
- R.Assign(3,3,20,5);
- Control:= new(PRadioButtons, Init(R,
- NewSItem('~1~2 hour',
- NewSItem('~2~4 hour',
- nil))));
- D^.Insert(Control);
-
- R.Assign(3,2,20,3);
- Control:= new(Plabel, Init(R, '~F~ormat', Control));
- D^.Insert(Control);
-
- R.Assign(3,6,20,7);
- Control:= new(PCheckBoxes, Init(R,
- NewSItem('~S~econds',
- nil)));
- D^.Insert(Control);
-
- R.Assign(16,9,20,10);
- Control:= new(PInputLine, Init(R, 2));
- D^.Insert(Control);
-
- R.Assign(2,8,20,9);
- Control:= new(PLabel, Init(R, '~R~efresh Rate', Control));
- D^.Insert(Control);
-
- R.Assign(2,9,15,10);
- Control:= new(PLabel, Init(R, '0-59 seconds', PLabel(Control)^.Link));
- D^.Insert(Control);
-
- R.Assign(21,3,31,5);
- Control:= new(PButton, Init(R, '~O~k', cmOk, bfDefault));
- D^.Insert(Control);
-
- R.Assign(21,6,31,8);
- Control:= new(PButton, Init(R, '~C~ancel', cmCancel, bfNormal));
- D^.Insert(Control);
-
-
- D^.SelectNext(False);
- D^.SetData(ClockData);
- repeat
- Command:= Desktop^.ExecView(D);
- if Command = cmOK then
- begin
- D^.GetData(ClockData);
- val(ClockData.RefreshStr,temp,code);
- if (code <> 0) or ((temp<0) or (temp>59)) then
- MessageBox('Refresh rate must be between 0 and 59 seconds.',nil,
- mfOKButton+mfError);
- end;
- until (Command = cmCancel)
- or ((code=0) and ((temp>=0) and (temp<=59)));
-
- Dispose(D, Done);
-
- if Command = cmOk then
- begin
- ClockOptions:= ClockData;
- SetRefreshStr(ClockData.RefreshStr);
- end;
-
- { update display to reflect changes immediately }
- TimeStr:= FormatTimeStr(LastTime.hour, LastTime.min, LastTime.sec);
- DrawView;
- end;
-
-
-
-
-
- procedure TClockMenu.HandleEvent( var Event: TEvent);
- begin
- TMenuBar.HandleEvent( Event);
- if Event.What = evCommand then
- begin
- case Event.Command of
- cmClockChangeDisplay: ClockChangeDisplay;
- cmClockSetAlarm: ;
- end;
- end;
- end;
-
-
-
-
- function TClockMenu.FormatTimeStr(h,m,s: word): string;
- var st, tail: string;
- begin
- tail:='';
- if ClockOptions.Format = Clock24Hour then
- st:= LeadingZero(h)
- else
- begin
- if h >= 12 then
- begin
- tail:= 'pm';
- if h>12 then
- dec(h,12);
- end
- else
- tail:= 'am';
- if h=0 then h:=12; {12 am}
- str(h:0,st); { no leading space on hours }
- end;
-
- st:=st+':'+ LeadingZero(m);
-
-
- if ClockOptions.Seconds = ClockDispSecs then
- st:= st+':'+LeadingZero(s);
-
- FormatTimeStr:= st + tail;
- end;
-
-
-
-
- end.
-
- { ----------------------------- DEMO ---------------------- }
-
- program TestPlatform;
-
- uses Objects, Drivers, Views, Menus, App,
- Dos, { for the paramcount and paramstr funcs}
- Clocks; { for the clock on the menubar object, TClockMenu }
-
- { This generic test platform has been hooked up to the clock-on-the-menubar
- object / unit. Search for *** to find hook-up points.
-
- Copyright (c) 1990 by Danny Thorpe
- }
-
-
- const cmNewWin = 100;
- cmFileOpen = 101;
-
- WinCount : Integer = 0;
- MaxLines = 50;
-
-
- type PInterior = ^TInterior;
- TInterior = object(TScroller)
- constructor init(var Bounds: TRect; AHScrollbar, AVScrollbar: PScrollbar);
- procedure Draw; virtual;
- end;
-
-
- PDemoWindow = ^TDemoWindow;
- TDemoWindow = object(TWindow)
- constructor Init(WindowNo: integer);
- end;
-
-
- TMyApp = object(TApplication)
- procedure InitStatusLine; virtual;
- procedure InitMenuBar; virtual;
- procedure NewWindow;
- procedure HandleEvent( var Event: TEvent); virtual;
- procedure Idle; virtual;
- end;
-
-
- var MyApp: TMyApp;
- Lines: array [0..MaxLines-1] of PString;
- LineCount: Integer;
-
-
- constructor TInterior.Init(var Bounds: TRect; AHScrollbar, AVScrollbar: PScrollbar);
- begin
- TScroller.Init(Bounds,AHScrollbar,AVScrollbar);
- Growmode := gfGrowHiX + gfGrowHiY;
- Options := Options or ofFramed;
- SetLimit(128,LineCount);
- end;
-
-
- procedure TInterior.Draw;
- var color: byte;
- y,i: integer;
- B: TDrawBuffer;
-
- begin
- TScroller.Draw;
- Color := GetColor($01);
- for y:= 0 to Size.Y -1 do
- begin
- MoveChar(B,' ',Color,Size.X);
- I := Delta.Y + Y;
- if (I<Linecount) and (Lines[I] <> nil) then
- MoveStr(B,Copy(Lines[I]^,Delta.X+1,size.x),Color);
- WriteLine(0,y,size.x,1,B);
- end;
- end;
-
-
- procedure ReadFile;
- var F: text;
- S: string;
-
- begin
- LineCount:=0;
- if paramcount = 0 then
- assign(F,'clockwrk.pas')
- else
- assign(F,paramstr(1));
- reset(F);
- while not eof(F) and (linecount < maxlines) do
- begin
- readln(f,s);
- Lines[Linecount] := NewStr(S);
- Inc(LineCount);
- end;
- Close(F);
- end;
-
-
-
-
-
- constructor TDemoWindow.Init(WindowNo: Integer);
- var LInterior, RInterior: PInterior;
- HScrollbar, VScrollbar: PScrollbar;
- R: TRect;
- Center: integer;
-
- begin
- R.Assign(0,0,40,15);
- R.Move(Random(40),Random(8));
-
- TWindow.Init(R, 'Window', wnNoNumber);
- GetExtent(R);
- Center:= (R.B.X + R.A.X) div 2;
- R.Assign(Center,R.A.Y+1,Center+1,R.B.Y-1);
- VScrollbar:= new(PScrollbar, Init(R));
- with VScrollbar^ do Options := Options or ofPostProcess;
- Insert(VScrollbar);
- GetExtent(R);
- R.Assign(R.A.X+2,R.B.Y-1,Center-1,R.B.Y);
- HScrollbar:= new(PScrollbar, Init(R));
- with HScrollbar^ do Options := Options or ofPostProcess;
- Insert(HScrollbar);
- GetExtent(R);
- R.Assign(R.A.X+1,R.A.Y+1,Center,R.B.Y-1);
- LInterior:= new(PInterior, Init(R, HScrollbar, VScrollbar));
- with LInterior^ do
- begin
- Options:= Options or ofFramed;
- Growmode:= GrowMode or gfGrowHiX;
- SetLimit(128,LineCount);
- end;
- Insert(LInterior);
-
- GetExtent(R);
- R.Assign(R.B.X-1,R.A.Y+1,R.B.X,R.B.Y-1);
- VScrollbar:= new(PScrollbar, Init(R));
- with VScrollbar^ do Options := Options or ofPostProcess;
- Insert(VScrollbar);
- GetExtent(R);
- R.Assign(Center+2,R.B.Y-1,R.B.X-2,R.B.Y);
- HScrollbar:= new(PScrollbar, Init(R));
- with HScrollbar^ do
- begin
- Options := Options or ofPostProcess;
- GrowMode:= GrowMode or gfGrowLoX;
- end;
- Insert(HScrollbar);
- GetExtent(R);
- R.Assign(Center+1,R.A.Y+1,R.B.X-1,R.B.Y-1);
- RInterior:= new(PInterior, Init(R, HScrollbar, VScrollbar));
- with RInterior^ do
- begin
- Options:= Options or ofFramed;
- Growmode:= GrowMode or gfGrowLoX;
- SetLimit(128,LineCount);
- end;
- Insert(RInterior);
- end;
-
-
-
-
- procedure TMyApp.InitStatusLine;
- var R: TRect;
-
- begin
- GetExtent(R); { find out how big the current view is }
- R.A.Y := R.B.Y-1; { squeeze R down to one line at bottom of frame }
- StatusLine := New(PStatusline, Init(R,
- NewStatusDef(0, $FFFF,
- NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
- NewStatusKey('~F4~ New', kbF4, cmNewWin,
- NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
- nil))),
- nil)
- ));
- end;
-
-
- { *** The vvv below indicate the primary hook-up point for the menubar-clock.
- This programmer-defined normal menu structure will be tacked onto the
- end of the clock menubar in TClockMenu.Init.
- }
-
- procedure TMyApp.InitMenuBar;
- var R: TRect;
-
- begin
- GetExtent(R); {***}
- r.b.y:= r.a.y+1; { vvv }
- Menubar := New(PClockMenu, Init(R, NewMenu(
- NewSubMenu('~F~ile', hcNoContext, NewMenu(
- NewItem('~O~pen','F3', kbF3, cmFileOpen, hcNoContext,
- NewItem('~N~ew','F4', kbF4, cmNewWin, hcNoContext,
- NewLine(
- NewItem('E~x~it','Alt-X', kbAltX, cmQuit, hcNoContext,
- nil))))),
- NewSubMenu('~W~indow', hcNoContext, NewMenu(
- NewItem('~N~ext','F6', kbF6, cmNext, hcNoContext,
- NewItem('~Z~oom','F7', kbF7, cmZoom, hcNoContext,
- nil))),
- nil)) { one ) for each menu defined }
- )));
- end;
-
-
- procedure TMyApp.NewWindow;
- var
- Window: PDemoWindow;
- R: TRect;
-
- begin
- inc(WinCount);
- Window:= New(PDemoWindow, Init(WinCount));
- Desktop^.Insert(Window);
- end;
-
-
-
-
- {*** clock hook-up point - typecasting required to access "new" method }
-
- procedure TMyApp.Idle;
- begin
- TApplication.Idle;
- PClockMenu(MenuBar)^.Update;
- end;
-
-
-
-
- procedure TMyApp.HandleEvent( var Event: TEvent);
- begin
- TApplication.HandleEvent(Event);
- if Event.What = evCommand then
- begin
- case Event.Command of
- cmNewWin: NewWindow;
- else { case }
- Exit;
- end; { case }
- ClearEvent(Event);
- end; {if}
- end;
-
-
-
-
-
-
-
-
- begin
-
- readfile;
-
- MyApp.Init;
- MyApp.run;
- MyApp.done;
- end.